# ui/qt6_tray_app.py
# -*- coding: utf-8 -*-
"""
纯 Qt6 托盘 + 原生右键菜单 + 气泡消息
"""
from pydoc import text
import sys
from PyQt6.QtWidgets import (
    QApplication, QSystemTrayIcon, QMenu, QMainWindow, QDialog
)
from PyQt6.QtCore import QTimer, Qt
from PyQt6.QtGui import QColor, QPen, QBrush, QPainter, QPixmap, QIcon, QMouseEvent
from pathlib import Path
from PyQt6.QtCore import QTimer
import csv
from datetime import datetime
# 添加缺失的导入
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils.input_dialogs import input_box, multi_input_box
from utils.logger import log  # 添加日志导入
from services.state_manager import set_state_direct

# --------------- 配置 ---------------
_TRAY_ICON_SIZE = 16        # 托盘图标尺寸
_STATE_COLOR = {
    None: "#808080",
    'DataWork': "#1e90ff",   # 天蓝色
    'Rework': "#ff8c00",     # 橙黄色
    'NonWork': "#808080",    # 灰色
    'Break': "#ff0000",      # 红色
}
_current_state = None
_float_win = None           # 将由外部注入

# --------------- 全局函数 ---------------
def refresh_icon(new_state):
    """刷新托盘图标颜色"""
    global _current_state
    _current_state = new_state
    
    # 更新所有托盘实例的图标
    app = QApplication.instance()
    if app:
        for widget in app.allWidgets():
            if isinstance(widget, QtTrayApp):
                widget._create_icon()

# --------------- 托盘应用 ---------------
class QtTrayApp(QMainWindow):
    def __init__(self, data_dir: str, user_id: str):
        super().__init__(None)
        self._data_dir = data_dir
        self._user_id = user_id
        QApplication.setQuitOnLastWindowClosed(False)
        self._tray = QSystemTrayIcon(self)
        self._tray.setToolTip("TimeTracker v6.0")
        
        # 添加汇总窗口引用
        self._summary_window = None
        
        self._create_icon()
        self._build_menu()

        # 左键单击 = 显/隐悬浮窗
        self._tray.activated.connect(self._on_tray_activated)
        
        # 注册状态监听 - 确保路径正确
        try:
            from core.signal_hub import add_state_listener
            add_state_listener(refresh_icon)
        except Exception as e:
            log(f'[ERR] 注册状态监听失败: {e}')

        self._tray.show()

        # 立即更新初始颜色
        from services.state_manager import state as current_state
        refresh_icon(current_state)
        log(f'[TRAY] 初始颜色已更新: {current_state}')

    def ask_open_summary(self):
        """线程安全：让主线程弹窗"""
        try:
            # 先释放文件锁，避免文件占用冲突
            from services.file_operations import release_all_locks
            release_all_locks()
            
            # 延迟打开，确保在主线程中执行
            QTimer.singleShot(100, self._open_summary_safe)
        except Exception as e:
            log(f'[ERR] 准备打开汇总窗口失败: {e}')

    def _open_summary_safe(self):
        """安全打开汇总窗口"""
        try:
            from ui.qt6_summary_window import show_summary_window
            
            # 释放文件锁
            from services.file_operations import release_all_locks
            release_all_locks()
            
            # 打开窗口并保持引用
            self._summary_window = show_summary_window(self._data_dir, self._user_id)
            
                
        except Exception as e:
            log(f'[ERR] 打开汇总窗口失败: {e}')
            self._tray.showMessage("打开失败", f"无法打开汇总窗口:\n{e}", 
                                QSystemTrayIcon.MessageIcon.Critical, 3000)
            
    # --------------- 生成彩色圆点图标 ---------------
    def _create_icon(self):
        pix = QPixmap(_TRAY_ICON_SIZE, _TRAY_ICON_SIZE)
        pix.fill(QColor(0, 0, 0, 0))  # 透明
        painter = QPainter(pix)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        color = QColor(_STATE_COLOR.get(_current_state, "#808080"))
        painter.setBrush(QBrush(color))
        painter.setPen(QPen(color, 0))
        painter.drawEllipse(2, 2, _TRAY_ICON_SIZE - 4, _TRAY_ICON_SIZE - 4)
        painter.end()
        self._tray.setIcon(QIcon(pix))

    # --------------- 构建右键菜单 ---------------
    def _build_menu(self):
        menu = QMenu()

        # 1. 一级菜单最上面：显示/隐藏悬浮窗
        menu.addAction("显示/隐藏悬浮窗", self._toggle_float_window)

        menu.addSeparator()

        # ✅ 新菜单：第1组
        menu.addAction("📊 记录工作量", self._on_record_workload)
        menu.addAction("✏️ 纠错当前行", self._on_correct_workload)

        menu.addSeparator()  # 横线隔开

        # ✅ 新菜单：第2组
        menu.addAction("➕ 开始新任务", self._on_new_task)
        menu.addAction("🔧 改返修", self._on_rework)


        menu.addSeparator()

        # 2. 非作业状态（二级菜单）
        non_work_menu = QMenu("非作业状态", self)
        non_work_menu.addAction("开会",  lambda: self._change_state_with_note('NonWork', '开会'))
        non_work_menu.addAction("培训",  lambda: self._change_state_with_note('NonWork', '培训'))
        non_work_menu.addAction("协助",  lambda: self._change_state_with_note('NonWork', '协助管理'))
        menu.addAction("🛑 休息", lambda: self._change_state('Break'))
        menu.addMenu(non_work_menu)
        menu.addSeparator()

        # 3. 查看（二级）
        view_menu = QMenu("查看", self)
        view_menu.addAction("日志目录", self._open_logs_folder)
        view_menu.addAction("今日汇总(Qt6)", self.ask_open_summary)
        if self._user_id.lower().startswith("admin"):
            view_menu.addAction("👑 管理员汇总", self._open_admin_summary)
        menu.addMenu(view_menu)

        # 4. 设置（二级）
        settings_menu = QMenu("设置", self)
        settings_menu.addAction("立即同步", self._force_sync)
        settings_menu.addAction("检查更新", self._check_update)
        settings_menu.addAction("配置链接", self._setup_git_config)  
        settings_menu.addSeparator()
        settings_menu.addAction("退出程序", self._quit)   
        menu.addMenu(settings_menu)

        self._tray.setContextMenu(menu)

    def _change_state_with_note(self, st, topic):
        """非作业子菜单：不再弹窗，直接切状态"""
        from services.state_manager import set_state, remark_buffer

        remark_buffer = ''          # 不留备注
        set_state(topic, manual=True)
    def _open_admin_summary(self):
        """打开管理员汇总窗口"""
        try:
            # 先释放文件锁
            from services.file_operations import release_all_locks
            release_all_locks()
            
            # 延迟打开，确保在主线程中执行
            from PyQt6.QtCore import QTimer
            QTimer.singleShot(100, self._open_admin_summary_safe)
        except Exception as e:
            log(f'[ERR] 准备打开管理员汇总窗口失败: {e}')

    def _open_admin_summary_safe(self):
        """安全打开管理员汇总窗口"""
        try:
            from ui.qt6_admin_summary import show_admin_summary_window
            
            # 释放文件锁
            from services.file_operations import release_all_locks
            release_all_locks()
            
            # 打开窗口并保持引用
            self._admin_summary_window = show_admin_summary_window(self._data_dir)
            
        except Exception as e:
            log(f'[ERR] 打开管理员汇总窗口失败: {e}')
            self._tray.showMessage("打开失败", f"无法打开管理员汇总窗口:\n{e}", 
                                QSystemTrayIcon.MessageIcon.Critical, 3000)
    # --------------- 添加缺失的状态切换方法 ---------------
    def _change_state(self, st):
        """切换状态"""
        try:
            # 导入状态管理器
            from services.state_manager import set_state
            # 调用状态切换
            set_state(st, manual=True)
            # 显示提示消息
            from utils.constants import STATE_MAP
            state_name = STATE_MAP.get(st, st)
            self._tray.showMessage("状态已切换", f"当前：{state_name}", 
                                QSystemTrayIcon.MessageIcon.Information, 1000)
            log(f'[TRAY] 用户切换状态: {state_name}')
        except Exception as e:
            log(f'[ERR] 切换状态失败: {e}')
            self._tray.showMessage("切换失败", f"错误：{e}", 
                                QSystemTrayIcon.MessageIcon.Critical, 2000)

    # --------------- 左键单击 ---------------
    def _on_tray_activated(self, reason):
        if reason == QSystemTrayIcon.ActivationReason.Trigger:  # 左键
            if _float_win:
                if _float_win.isVisible():
                    _float_win.hide()
                else:
                    _float_win.show()
                    _float_win.raise_()
                    _float_win.activateWindow()

    # --------------- 打开汇总窗口 ---------------
    def _open_summary(self):
        """主线程弹窗（被 QTimer 回调）"""
        try:
            # 先释放文件锁
            from services.file_operations import release_all_locks
            release_all_locks()
            
            # 然后打开汇总窗口
            from ui.qt6_summary_window import show_summary_window
            show_summary_window(self._data_dir, self._user_id)
        except Exception as e:
            log(f'[ERR] 打开汇总窗口失败: {e}')
            self._tray.showMessage("打开失败", f"错误：{e}", 
                                QSystemTrayIcon.MessageIcon.Critical, 2000)

    def _open_logs_folder(self):
        """主线程打开日志目录"""
        import subprocess
        logs = Path(self._data_dir) / "logs"
        subprocess.Popen(['explorer', str(logs)])

    def _force_sync(self):
        """主线程立即同步"""
        from git_sync import GitSyncManager
        mgr = GitSyncManager(self._data_dir, self._user_id)
        ok = mgr.sync()
        self._tray.showMessage("同步结果", "成功" if ok else "失败", QSystemTrayIcon.MessageIcon.Information, 1500)

    def _check_update(self):
        """主线程检查更新"""
        from update import do_update
        need = do_update()
        if need:
            self._tray.showMessage("发现新版本", "程序即将重启更新", QSystemTrayIcon.MessageIcon.Information, 2000)

    # --------------- 退出 ---------------
    def _quit(self):
        """退出程序 - 需要密码验证"""
        
        # 1. 先弹出密码输入窗口
        from utils.input_dialogs import input_box
        from utils.constants import EXIT_PWD
        
        # 弹出密码输入窗口
        password = input_box('密码验证', '请输入密码以退出程序:', mask=True)
        
        # 2. 检查密码是否正确
        if password == EXIT_PWD:
            # 密码正确，执行退出
            
            # 先保存当前的工作记录
            from services.state_manager import log_end
            log_end()
            
            # 释放文件锁（避免文件被占用）
            from services.file_operations import release_all_locks
            release_all_locks()
            
            # 隐藏托盘图标
            self._tray.hide()
            
            # 退出程序
            from PyQt6.QtWidgets import QApplication
            QApplication.quit()
            
        else:
            # 密码错误，显示提示
            self._tray.showMessage(
                "密码错误", 
                "退出密码不正确，程序继续运行",
                QSystemTrayIcon.MessageIcon.Warning, 
                2000
            )

    def _setup_git_config(self):
        """配置 Git 同步链接"""
        try:
            from utils.input_dialogs import input_box
            
            # 获取当前配置
            from git_sync import GitSyncManager
            git_mgr = GitSyncManager(self._data_dir, self._user_id)
            current_repo = git_mgr.repo_url or ""
            
            # 弹窗输入新的仓库URL
            repo_url = input_box('配置同步链接', '请输入Gitee仓库URL:', current_repo)
            if not repo_url:
                return

            if not repo_url.endswith('.git'):
                repo_url += '.git'

            access_token = input_box('配置同步链接', '请输入Gitee访问令牌:', mask=True)
            if not access_token:
                return

            # 配置同步
            success = git_mgr.setup(url=repo_url, token=access_token)
            if success:
                self._tray.showMessage("配置成功", "同步链接配置成功！", 
                                    QSystemTrayIcon.MessageIcon.Information, 2000)
                log('[SETTINGS] 同步链接配置成功')
            else:
                self._tray.showMessage("配置失败", "同步链接配置失败", 
                                    QSystemTrayIcon.MessageIcon.Warning, 2000)
                
        except Exception as e:
            log(f'[ERR] 配置同步链接失败: {e}')
            self._tray.showMessage("配置失败", f"配置失败:\n{e}", 
                                QSystemTrayIcon.MessageIcon.Critical, 3000)
    def _toggle_float_window(self):
        """显示/隐藏悬浮窗"""
        try:
            from ui.qt6_float_window import toggle_qt_float_window
            toggle_qt_float_window()
            
            # 获取当前悬浮窗状态
            from ui.qt6_float_window import _float_win, _float_alive
            is_visible = _float_win and _float_alive and _float_win.isVisible()
            
            if is_visible:
                message = "悬浮窗已显示"
                log('[TRAY] 显示悬浮窗')
            else:
                message = "悬浮窗已隐藏" 
                log('[TRAY] 隐藏悬浮窗')
                
            self._tray.showMessage("悬浮窗", message, 
                                QSystemTrayIcon.MessageIcon.Information, 1000)
                                
        except Exception as e:
            log(f'[ERR] 切换悬浮窗显示失败: {e}')
            self._tray.showMessage("操作失败", f"切换悬浮窗失败:\n{e}", 
                                QSystemTrayIcon.MessageIcon.Critical, 2000)    
            
    def _on_record_workload(self):
        print("[MENU] 点击了：记录工作量 - 开始")
        
        try:
            from ui.qt6_input_dialog import qt_workload_box
            
            # 循环直到用户输入有效数字或取消
            while True:
                action, workload = qt_workload_box(parent=self)

                if action is None:  # 用户取消
                    print("[MENU] 用户取消了记录工作量")
                    return

                if not workload or not workload.isdigit():
                    from PyQt6.QtWidgets import QMessageBox
                    QMessageBox.warning(self, "输入错误", "请输入有效的数字！")
                    continue  # 重新弹出输入窗口
                else:
                    break  # 输入正确，退出循环

            print(f"[MENU] 用户选择: {action}, 工作量: {workload}")

            # ★★★ 获取当前状态
            from services.state_manager import state as current_state
            print(f"[MENU] 当前状态: {current_state}")

            if action == "提交任务":
                print("[MENU] 用户选择提交任务")
                
                # ★★★ 修改逻辑：作业状态才检查工作量，非作业状态直接新建行
                if current_state in ['DataWork', 'Rework']:
                    # 作业状态：检查工作量
                    if self._current_row_has_workload():
                        print("[MENU] 作业状态且当前行已有工作量，创建新行记录工作量")
                        success = self._create_new_row_with_same_fields(workload)
                        if success:
                            print("[MENU] 新行创建成功")
                        else:
                            print("[MENU] 新行创建失败")
                else:
                    # 非作业状态：直接新建行
                    print("[MENU] 非作业状态，直接创建新行记录工作量")
                    success = self._create_new_row_with_same_fields(workload)
                    if success:
                        print("[MENU] 新行创建成功")
                    else:
                        print("[MENU] 新行创建失败")
                
                # ② 结束当前行（补填结束时间）
                from services.state_manager import _close_previous_segment
                from datetime import datetime
                _close_previous_segment(datetime.now())

                # ③ 问用户要不要开新任务 - 使用按钮选择
                from ui.qt6_input_dialog import TwoButtonDialog
                choice = TwoButtonDialog(
                    "任务已完成",
                    "请选择下一步操作：",
                    "开始新任务", 
                    "休息一下",
                    parent=self
                ).exec()

                print(f"[MENU] 用户选择: {choice}")

                if choice == 1:  # 开始新任务
                    print("[MENU] 用户选择开始新任务")
                    # ④ 弹"新任务"框
                    from utils.input_dialogs import multi_input_box
                    prompts = []
                    
                    # 循环直到用户输入有效或取消
                    while True:
                        values = multi_input_box(
                            title="开始新任务", 
                            prompts=prompts, 
                            default_values=[], 
                            parent=self
                        )
                        
                        # 检查用户是否取消输入
                        if values is None:
                            print("[MENU] 用户取消了开始新任务")
                            # 用户取消开始新任务，直接切换到休息
                            from services.state_manager import set_state
                            set_state("Break", manual=True)
                            self._tray.showMessage("已休息", "用户取消开始新任务，已切换到休息", 
                                QSystemTrayIcon.MessageIcon.Information, 1500)
                            return
                            
                        # 检查返回值长度
                        if not values or len(values) != 4:
                            print("[MENU] 输入信息不完整")
                            from PyQt6.QtWidgets import QMessageBox
                            QMessageBox.warning(self, "输入不完整", "请填写所有信息！")
                            continue  # 重新弹出输入窗口

                        project, task_id, workload1, remark = values

                        # 验证任务ID和工作量
                        if not task_id.strip():
                            from PyQt6.QtWidgets import QMessageBox
                            QMessageBox.warning(self, "输入错误", "任务ID不能为空！")
                            continue
                        
                        if not workload1.strip().isdigit():
                            from PyQt6.QtWidgets import QMessageBox
                            QMessageBox.warning(self, "输入错误", "工作量必须是数字！")
                            continue
                        
                        break  # 所有验证通过，退出循环

                    # 使用安全的开始新任务方法
                    print(f"[DEBUG] 准备开始新任务: project={project}, task_id={task_id}")
                    try:
                        from services.state_manager import _last_work, set_state_direct
                        success = set_state_direct(
                            _last_work,  # 使用上次的工作状态
                            project_name=project,
                            work_type="数据更新",
                            task_id=task_id,
                            workload1=workload1,
                            remark=remark,
                            manual=True
                        )

                        print(f"[DEBUG] set_state_direct 返回: {success}")
                        
                        if success:
                            self._tray.showMessage("新任务已开", f"任务ID：{task_id}", 
                                                QSystemTrayIcon.MessageIcon.Information, 1500)
                            print("[DEBUG] 新任务开始成功")
                        else:
                            print("[DEBUG] 开始新任务失败，切换到休息")
                            # 如果开始新任务失败，切换到休息
                            from services.state_manager import set_state
                            set_state("Break", manual=True)
                            self._tray.showMessage("已休息", "开始新任务失败，已切换到休息", 
                                QSystemTrayIcon.MessageIcon.Information, 1500)
                            
                    except Exception as e:
                        print(f"[ERROR] 开始新任务异常: {e}")
                        # 发生异常时切换到休息
                        from services.state_manager import set_state
                        set_state("Break", manual=True)
                        self._tray.showMessage("错误", f"开始新任务时出错：{e}", 
                            QSystemTrayIcon.MessageIcon.Warning, 2000)
                    
                    # 无论成功与否，都显示提交完成消息
                    self._tray.showMessage("提交完成", "当前任务已结束", 
                                        QSystemTrayIcon.MessageIcon.Information, 1000)
                    print("[DEBUG] 记录工作量流程完成")

                elif choice == 2:  # 休息一下
                    print("[MENU] 用户选择休息")
                    from services.state_manager import set_state
                    set_state("Break", manual=True)
                    self._tray.showMessage("已休息", "当前任务结束，已切换到休息", 
                        QSystemTrayIcon.MessageIcon.Information, 1500)
                else:  # 用户关闭窗口
                    print("[MENU] 用户关闭选择窗口")
                    from services.state_manager import set_state
                    set_state("Break", manual=True)
                    self._tray.showMessage("已休息", "当前任务结束，已切换到休息", 
                        QSystemTrayIcon.MessageIcon.Information, 1500)
                    
                self._tray.showMessage("提交完成", "当前任务已结束", 
                                    QSystemTrayIcon.MessageIcon.Information, 1000)

            else:  # 继续任务
                print("[MENU] 用户选择继续任务")
                
                # ★★★ 修改逻辑：作业状态才检查工作量，非作业状态直接新建行
                if current_state in ['DataWork', 'Rework']:
                    # 作业状态：检查工作量
                    if self._current_row_has_workload():
                        print("[MENU] 作业状态且当前行已有工作量，创建新行记录工作量")
                        success = self._create_new_row_with_same_fields(workload)
                        if success:
                            self._tray.showMessage("记录成功", f"已新建行记录工作量：{workload}", 
                                                QSystemTrayIcon.MessageIcon.Information, 1000)
                        else:
                            self._tray.showMessage("记录失败", "新建行失败，请重试", 
                                                QSystemTrayIcon.MessageIcon.Warning, 2000)
                    else:
                        print("[MENU] 作业状态且当前行无工作量，更新当前行")
                        from services.file_operations import _update_current_row_workload
                        success = _update_current_row_workload(workload)
                        if success:
                            self._tray.showMessage("记录成功", f"工作量已记录：{workload}", 
                                                QSystemTrayIcon.MessageIcon.Information, 1000)
                        else:
                            self._tray.showMessage("记录失败", "更新工作量失败，请重试", 
                                                QSystemTrayIcon.MessageIcon.Warning, 2000)
                else:
                    # 非作业状态：直接新建行
                    print("[MENU] 非作业状态，直接创建新行记录工作量")
                    success = self._create_new_row_with_same_fields(workload)
                    if success:
                        self._tray.showMessage("记录成功", f"已新建行记录工作量：{workload}", 
                                            QSystemTrayIcon.MessageIcon.Information, 1000)
                    else:
                        self._tray.showMessage("记录失败", "新建行失败，请重试", 
                                            QSystemTrayIcon.MessageIcon.Warning, 2000)
        
        except Exception as e:
            print(f"[MENU] 记录工作量异常: {e}")
            import traceback
            traceback.print_exc()
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.critical(self, "错误", f"记录工作量时出错:\n{e}")
        
        print("[MENU] 记录工作量流程完成 - 正常结束")

    def _get_last_row_4_fields(self):
        """返回今天最后一行的 [项目,类型,ID,框量] ，如果没有就返回空列表"""
        from services.file_operations import _log_dir, _user_id
        today = datetime.now().strftime('%Y-%m-%d')
        today_file = os.path.join(_log_dir, f'{today}_{_user_id}.csv')
        if not os.path.exists(today_file):
            return []
        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        if len(rows) <= 1:               # 只有表头
            return []
        last = rows[-1]
        # 列序号按你原来模板：9=项目 10=类型 11=ID 12=框量
        project   = last[9]  if len(last) > 9  else ''
        work_type = last[10] if len(last) > 10 else ''
        task_id   = last[11] if len(last) > 11 else ''
        workload1 = last[12] if len(last) > 12 else ''
        return [project, work_type, task_id, workload1]  

    def _overwrite_last_row_4_fields(self, project, work_type, task_id, workload1):
        """把今天最后一行的 4 个字段原地覆盖，成功返回 True"""
        from services.file_operations import _log_dir, _user_id
        today = datetime.now().strftime('%Y-%m-%d')
        today_file = os.path.join(_log_dir, f'{today}_{_user_id}.csv')
        if not os.path.exists(today_file):
            return False

        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        if len(rows) <= 1:
            return False

        # 改最后一行
        last = rows[-1]
        # 确保列够长
        while len(last) < 13:
            last.append('')
        last[9]  = project
        last[10] = work_type
        last[11] = task_id
        last[12] = workload1

        # 写回
        with open(today_file, 'w', encoding='utf-8-sig', newline='') as f:
            writer = csv.writer(f)
            writer.writerows(rows)
        return True
    def _get_last_row_6_fields(self):
        """返回今天最后一行的 [项目,类型,ID,工作量1,工作量2,备注] ，如果没有就返回空列表"""
        from services.file_operations import _log_dir, _user_id
        import csv
        from datetime import datetime
        
        today = datetime.now().strftime('%Y-%m-%d')
        today_file = os.path.join(_log_dir, f'{today}_{_user_id}.csv')
        if not os.path.exists(today_file):
            return []
        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        if len(rows) <= 1:               # 只有表头
            return []
        last = rows[-1]
        # 列序号：9=项目 10=类型 11=ID 12=工作量1 13=工作量2 15=备注
        project   = last[9]  if len(last) > 9  else ''
        work_type = last[10] if len(last) > 10 else ''
        task_id   = last[11] if len(last) > 11 else ''
        workload1 = last[12] if len(last) > 12 else ''
        workload2 = last[13] if len(last) > 13 else ''
        remark    = last[15] if len(last) > 15 else ''
        return [project, work_type, task_id, workload1, workload2, remark]

    def _overwrite_last_row_6_fields(self, project, work_type, task_id, workload1, workload2, remark):
        """把今天最后一行的 6 个字段原地覆盖，成功返回 True"""
        from services.file_operations import _log_dir, _user_id
        import csv
        from datetime import datetime
        
        today = datetime.now().strftime('%Y-%m-%d')
        today_file = os.path.join(_log_dir, f'{today}_{_user_id}.csv')
        if not os.path.exists(today_file):
            return False

        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        if len(rows) <= 1:
            return False

        # 改最后一行
        last = rows[-1]
        # 确保列够长
        while len(last) < 16:
            last.append('')
        last[9]  = project
        last[10] = work_type
        last[11] = task_id
        last[12] = workload1
        last[13] = workload2
        last[15] = remark

        # 写回
        with open(today_file, 'w', encoding='utf-8-sig', newline='') as f:
            writer = csv.writer(f)
            writer.writerows(rows)
        return True  

    def _on_correct_workload(self):
        """纠错当前行：弹出 6 格窗，预填当前值，确定后原地覆盖"""
        from ui.qt6_input_dialog import MultiInputDialog
        from PyQt6.QtWidgets import QMessageBox, QDialog

        # 1. 拿当前行的字段值（需要扩展到6个字段）
        old_vals = self._get_last_row_6_fields()  # ★★★ 修改：改为获取6个字段
        if not old_vals:
            QMessageBox.warning(self, "无记录", "今天还没有任何记录，无法纠错。")
            return

        # 2. 取最近3条作业类型
        recent_wt = self._recent_work_types(3)

        # 3. 弹窗（6个输入口）
        dlg = MultiInputDialog(
            title="纠错当前行",
            prompts = [],
            default_values=old_vals,
            combo_items=recent_wt,
            header_text="✏️ 请修改——当前行信息",
            parent=self
        )

        if dlg.exec() != QDialog.DialogCode.Accepted:
            return
        new_vals = dlg.get_values()
        if new_vals is None or len(new_vals) != 6:  # ★★★ 修改：检查6个值
            return

        project, work_type, task_id, workload1, workload2, remark = [v.strip() for v in new_vals]

        # 4. 写回文件
        ok = self._overwrite_last_row_6_fields(project, work_type, task_id, workload1, workload2, remark)  # ★★★ 修改
        if ok:
            self._tray.showMessage("纠错完成", "当前行已更新", QSystemTrayIcon.MessageIcon.Information, 1500)
        else:
            QMessageBox.warning(self, "纠错失败", "更新时出错，请稍后再试。")

    def _recent_work_types(self, limit=3):
        """返回今天用过的最后 limit 个不重复的'作业类型'，倒序（最新在前）"""
        from services.file_operations import _log_dir, _user_id
        import os, csv
        from datetime import datetime

        today_file = os.path.join(_log_dir, f'{datetime.now():%Y-%m-%d}_{_user_id}.csv')
        if not os.path.exists(today_file):
            return []

        seen = set()
        recent = []               # 倒序装结果
        # 从后往前读，最新在行尾
        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        for row in reversed(rows[1:]):        # 跳过表头
            wt = row[10].strip() if len(row) > 10 else ''
            if wt and wt not in seen:
                seen.add(wt)
                recent.append(wt)
                if len(recent) == limit:
                    break
        return recent
    
    def _on_rework(self):
        """改返修：直接切到"处理返修”→弹6格窗→新增一行→重新开始计时"""
        print("[MENU] 点击了：改返修")
        try:
            from PyQt6.QtWidgets import QMessageBox
            from datetime import datetime
            from services.state_manager import _close_previous_segment, _start_new_segment
            from ui.qt6_input_dialog import MultiInputDialog

            # ★★★ 新增：检查当前状态和是否有工作量
            from services.state_manager import state as current_state
            
            # 如果当前是工作状态且当前行没有工作量，先记录工作量
            if current_state in ['DataWork', 'Rework'] and self._current_row_has_workload() == False:
                print("[MENU] 当前行没有工作量，先记录工作量")
                
                # 弹出记录工作量窗口
                from ui.qt6_input_dialog import qt_workload_box
                action, workload = qt_workload_box(parent=self)
                
                if action is None:  # 用户取消
                    print("[MENU] 用户取消了记录工作量，改返修中止")
                    return
                    
                if not workload or not workload.isdigit():
                    QMessageBox.warning(self, "输入错误", "请输入有效的数字！")
                    return
                    
                # 记录工作量到当前行
                from services.file_operations import _update_current_row_workload
                success = _update_current_row_workload(workload)
                if success:
                    self._tray.showMessage("记录成功", f"工作量已记录：{workload}", 
                                        QSystemTrayIcon.MessageIcon.Information, 1000)
                else:
                    self._tray.showMessage("记录失败", "更新工作量失败，请重试", 
                                        QSystemTrayIcon.MessageIcon.Warning, 2000)
                    return

            # 1. 先封尾当前行（如果正在作业）
            now = datetime.now()
            _close_previous_segment(now)

            # 2. 取最近3条作业类型历史（给下拉用）
            recent_wt = self._recent_work_types(3)

            # 3. 弹窗（6个输入口）
            # 循环直到用户输入有效或取消
            while True:
                dlg = MultiInputDialog(
                    title="改返修：处理返修",
                    prompts = [],
                    default_values=["", "", "", "", "", ""],  
                    combo_items=recent_wt,
                    header_text="🔧 请填写——返修任务信息",
                    parent=self
                )
                if dlg.exec() != MultiInputDialog.DialogCode.Accepted:
                    return  # 用户取消

                values = dlg.get_values()
                if not values or len(values) != 6:  # ★★★ 修改：检查6个值
                    continue  # 重新弹出

                project, work_type, task_id, workload1, workload2, remark = [v.strip() for v in values]

                # 4. 简单校验
                if not task_id:
                    QMessageBox.warning(self, "输入错误", "任务ID不能为空！")
                    continue
                    
                if not workload1 or not workload1.isdigit():
                    QMessageBox.warning(self, "输入错误", "工作量必须是数字！")
                    continue
                    
                break  # 验证通过，退出循环

            # 先补填上一段（如果正在计时）
            _close_previous_segment(now)

            # 6. 使用新的函数开始改返修任务，直接设置任务信息
            success = set_state_direct(
                'Rework',  # 固定状态为 Rework
                project_name=project,
                work_type=work_type,  # ★★★ 修改：使用用户选择的作业类型
                task_id=task_id,
                workload1=workload1,
                workload2=workload2,  # ★★★ 新增：传入初始框量
                remark=remark,
                manual=True
            )

            if not success:
                QMessageBox.warning(self, "错误", "改返修任务失败，请检查输入信息")
                return

            # 7. 提示
            self._tray.showMessage(
                "改返修已记录",
                f"任务ID：{task_id}",
                QSystemTrayIcon.MessageIcon.Information,
                1500
            )

        except Exception as e:
            print("[ERROR] 改返修失败：", e)
            QMessageBox.critical(self, "出错", f"改返修时出错：\n{e}")

    def _on_new_task(self):
        """开始新任务：直接切到"数据更新”→弹6格窗→新增一行→重新开始计时"""
        print("[MENU] 点击了：开始新任务")
        try:
            from PyQt6.QtWidgets import QMessageBox
            from datetime import datetime
            from services.state_manager import _close_previous_segment, _start_new_segment
            from ui.qt6_input_dialog import MultiInputDialog

            print("[DEBUG] 步骤1: 检查当前状态")
            # ★★★ 新增：检查当前状态和是否有工作量
            from services.state_manager import state as current_state
            
            # 如果当前是工作状态且当前行没有工作量，先记录工作量
            if current_state in ['DataWork', 'Rework'] and self._current_row_has_workload() == False:
                print("[MENU] 当前行没有工作量，先记录工作量")
                
                # 弹出记录工作量窗口
                from ui.qt6_input_dialog import qt_workload_box
                action, workload = qt_workload_box(parent=self)
                
                if action is None:  # 用户取消
                    print("[MENU] 用户取消了记录工作量，开始新任务中止")
                    return
                    
                if not workload or not workload.isdigit():
                    QMessageBox.warning(self, "输入错误", "请输入有效的数字！")
                    return
                    
                # 记录工作量到当前行
                from services.file_operations import _update_current_row_workload
                success = _update_current_row_workload(workload)
                if success:
                    self._tray.showMessage("记录成功", f"工作量已记录：{workload}", 
                                        QSystemTrayIcon.MessageIcon.Information, 1000)
                else:
                    self._tray.showMessage("记录失败", "更新工作量失败，请重试", 
                                        QSystemTrayIcon.MessageIcon.Warning, 2000)
                    return

            print("[DEBUG] 步骤2: 封尾当前行")
            # 1. 先封尾当前行（如果正在作业）
            now = datetime.now()
            _close_previous_segment(now)

            print("[DEBUG] 步骤3: 获取历史记录")
            # 2. 取最近3条作业类型历史（给下拉用）
            recent_wt = self._recent_work_types(3)

            print("[DEBUG] 步骤4: 创建弹窗")
            # 3. 弹窗（6个输入口）
            dlg = MultiInputDialog(
                title="开始新任务：数据更新",
                prompts = [],
                default_values=["", "", "", "", "", ""],
                combo_items=recent_wt,
                header_text="📝 请填写——新任务信息",
                parent=self
            )
            
            print("[DEBUG] 步骤5: 显示弹窗")
            if dlg.exec() != MultiInputDialog.DialogCode.Accepted:
                print("[DEBUG] 用户取消")
                return

            print("[DEBUG] 步骤6: 获取输入值")
            values = dlg.get_values()
            if not values or len(values) != 6:
                print("[DEBUG] 输入值无效")
                return

            project, work_type, task_id, workload1, workload2, remark = [v.strip() for v in values]

            print(f"[DEBUG] 步骤7: 输入值 - 项目:{project}, 类型:{work_type}, ID:{task_id}, 工作量:{workload1}, 框量:{workload2}, 备注:{remark}")

            # 4. 简单校验
            if not task_id or not workload1.isdigit():
                QMessageBox.warning(self, "输入错误", "任务ID不能为空，且工作量必须是数字！")
                return

            print("[DEBUG] 步骤8: 调用 set_state_direct")
            # 5. 固定状态为 DataWork
            state_key = 'DataWork'

            # 6. 使用新的函数开始新任务，直接设置任务信息
            from services.state_manager import set_state_direct
            success = set_state_direct(
                state_key,
                project_name=project,
                work_type=work_type,
                task_id=task_id,
                workload1=workload1,
                workload2=workload2,
                remark=remark,
                manual=True
            )

            if not success:
                QMessageBox.warning(self, "错误", "开始新任务失败，请检查输入信息")
                return

            print("[DEBUG] 步骤9: 显示提示消息")
            # 7. 提示
            self._tray.showMessage(
                "新任务已开启",
                f"项目：{project}\n任务ID：{task_id}",
                QSystemTrayIcon.MessageIcon.Information,
                1500
            )

            print("[DEBUG] 步骤10: 完成")

        except Exception as e:
            print(f"[ERROR] 开始新任务失败：{e}")
            import traceback
            traceback.print_exc()
            QMessageBox.critical(self, "出错", f"开始新任务时出错：\n{e}")

    def _get_last_row_full_info(self):
        """获取今天最后一行的完整信息"""
        from services.file_operations import _log_dir, _user_id
        import csv
        from datetime import datetime
        
        today = datetime.now().strftime('%Y-%m-%d')
        today_file = os.path.join(_log_dir, f'{today}_{_user_id}.csv')
        
        if not os.path.exists(today_file):
            return None
        
        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        
        if len(rows) <= 1:  # 只有表头
            return None
        
        last_row = rows[-1]
        # 返回完整的行信息
        return last_row

    def _current_row_has_workload(self):
        """检查当前最后一行是否有工作量"""
        # 还是需要从CSV文件检查当前行是否有工作量
        from services.file_operations import _log_dir, _user_id
        import csv
        from datetime import datetime
        
        today = datetime.now().strftime('%Y-%m-%d')
        today_file = os.path.join(_log_dir, f'{today}_{_user_id}.csv')
        
        if not os.path.exists(today_file):
            return False
        
        with open(today_file, 'r', encoding='utf-8-sig', newline='') as f:
            rows = list(csv.reader(f))
        
        if len(rows) <= 1:  # 只有表头
            return False
        
        last_row = rows[-1]
        # 工作量1在第13列（索引12）
        if len(last_row) > 12:
            workload = last_row[12].strip()
            return workload != '' and workload.isdigit()
        return False

    def _create_new_row_with_same_fields(self, new_workload):
        """创建新行，直接从任务标识获取字段，只修改工作量"""
        from services.state_manager import set_state_direct, _current_task_key, _get_default_values_from_task_key
        from datetime import datetime
        
        # ★★★ 直接从任务标识获取字段
        print(f"[DEBUG] 开始创建新行，当前任务标识: {_current_task_key}")
        
        if not _current_task_key:
            print("[MENU] 错误：没有可用的任务标识")
            # ★★★ 尝试获取最近的任务信息
            from services.state_manager import task_id_buffer, _state_task_id, state as current_state
            print(f"[DEBUG] 备选信息 - task_id_buffer: {task_id_buffer}, _state_task_id: {_state_task_id}, 当前状态: {current_state}")
            return False
        
        defaults = _get_default_values_from_task_key()
        project_name = defaults.get('project_name', '')
        work_type = defaults.get('work_type', '')
        task_id = defaults.get('task_id', '')
        workload2 = defaults.get('workload2', '')  # ★★★ 新增：获取工作量2
        
        print(f"[DEBUG] 从任务标识解析结果: 项目='{project_name}', 类型='{work_type}', 任务ID='{task_id}', 框量='{workload2}'")
        
        # 获取当前状态
        from services.state_manager import state as current_state
        
        # ★★★ 如果是非作业状态，使用最近的作业状态
        target_state = current_state
        if current_state not in ['DataWork', 'Rework']:
            from services.state_manager import _last_work
            target_state = _last_work
            print(f"[DEBUG] 非作业状态 {current_state}，使用最近作业状态 {target_state}")
        
        # ★★★ 最终检查：如果字段不完整，使用默认值
        if not project_name:
            project_name = "默认项目"
            print("[DEBUG] 使用默认项目名称")
        if not work_type:
            work_type = "数据更新"
            print("[DEBUG] 使用默认作业类型")
        if not task_id:
            # 生成一个默认的任务ID（使用时间戳）
            task_id = str(int(datetime.now().timestamp()))[-6:]
            print(f"[DEBUG] 使用默认任务ID: {task_id}")
        if not workload2:
            workload2 = "0"  # ★★★ 如果没有框量，设为0
            print("[DEBUG] 使用默认框量: 0")
        
        # 使用 set_state_direct 创建新行
        print(f"[DEBUG] 准备创建新行: 状态={target_state}, 项目={project_name}, 类型={work_type}, 任务ID={task_id}, 工作量={new_workload}, 框量={workload2}")
        
        success = set_state_direct(
            target_state,  # 使用目标状态
            project_name=project_name,
            work_type=work_type,
            task_id=task_id,
            workload1=new_workload,
            workload2=workload2,  # ★★★ 新增：传入工作量2
            remark="",  # 备注留空
            manual=True
        )
        
        if success:
            print(f"[MENU] 新行创建成功: 状态={target_state}, 工作量={new_workload}, 框量={workload2}")
        else:
            print("[MENU] 新行创建失败")
        
        return success
    
# --------------- 外部唯一入口 ---------------
def create_qt_tray_app(data_dir: str, user_id: str):
    """主进程调用：返回 QtTrayApp 实例"""
    app = QApplication.instance() or QApplication(sys.argv)
    tray = QtTrayApp(data_dir, user_id)
    return tray